#!/bin/bash

# Script to take screenshots of web services discovered by nmap.
# Requires a patched copy of cutycapt (see http://joekuan.wordpress.com/2012/03/30/changes-to-make-cutycapt-bypassing-ssl-certificate-confirmation/ for details) and a grepable nmap file (*.gnmap).
# Ensure cutycapt is in /pentest/reporting/cutycapt
# built for Kali Linux.


# Version 0.41 - Added hard coded paths to patched vutcapt for use on Kali linux.
# Version 0.4 - Added -s option to search for all http/https services and give the user the option which to scan
# Version 0.33 - More regex playing and added compulsary output directory option.
# Version 0.32 - Added better regex to pick up when nmap is unsure (e.g. http?) and to try and make exact matches (e.g. 443 only and not 4443)
# Version 0.31 - Fixed success/failed count error
#              - Fixed problem with setting $service before the Ip loop.
# Version 0.3 - Added default port set, and the script will fall over to this if no ports set. Set up to allow multiple ports (eg -p "80 443"
#             - Added ability to look at the service nmap identifies and run the appropriate cutycapt command (http/https)
# Version 0.21 - Added output from error_catcher to monitor failed screenshots
# Version 0.2 - Changed out gnome-web-photo for a patched cutycapt to ignore ssl cert errors (to screenshot https on IP addresses)
#             - Added 8443/tcp into the "https" part of the loop
#             - Added simple error catching (error_catcher)
# Verison 0.1 - Basic functionality, set port and gnmap file and use gnome-web-shot to screenshot.

# to-do:
# Add error catching to make the output easier on the eyes - Done, albeit very simple.
# Extend the ssl part to try IP and hostname (if known).


# Set usage function and getopts
usage ()
{
echo "usage: $0 <options>

OPTIONS:
-h Show this message
-p Ports to search for, space delimited (eg -p \"80 443\")
-f Nmap file to search in (ensure this is grepable, -oG output e.g. *.gnmap)
-o Output directory
-s Search specified file for http/https services, and choose ports to screenshot

examples: 

nmapss.sh -p \"80 443\" -f scan-report.gnmap -o /tmp/screenshots/
nmapss.sh -s -f scan-report.gnmap -o /root/screenshots/

To screenshot default ports (80/tcp, 443/tcp, 8080/tcp, 8443/tcp), omit the -p switch

nmapss.sh -f scan-report.gnmap -o /tmp/screenshots/"
}

# Set variables required
portlist=
file=

# Set intial values for number of successful and failed screenshots
failed=0
success=0
notwebserv=0

# Set GETOPTS
while getopts "so:p:f:h" OPT; do
	case $OPT in
		h) usage; exit;;
		p) portlist=$OPTARG;;
		f) file=$OPTARG;;
		o) outputdir=$OPTARG;;
		s) autosearch="on";;
		*) usage; exit;;
	esac
done

# Verify file  and output directory have been specified
if [[ -z "$file" ]]
then
	echo ""
	echo "No scan file chosen (the -f switch)"
	echo ""
	usage
	exit
	
elif [[ -z "$outputdir" ]]
then
	echo ""
	echo "No output directory chosen (the -o switch)"
	echo ""
	usage
	exit
	
# If -s set, do auto searching, specifying ports etc
elif [[ "$autosearch" = on ]]
then
	summary=$(grep http $file | grep -o " [0-9]\+\/open\/tcp\/\/http[s]\?[?]\?\/" | sort -n | uniq -c | cut -d"/" -f1,3,5)
	total=$(grep http $file | grep -o " [0-9]\+\/open\/tcp\/\/http[s]\?[?]\?\/" | wc -l)
	echo "A total of $total web services found. Below is a summary:"
	echo ""
	echo "$summary"
	echo ""
	read -p "Do you want to screenshot all of these ports? [Y/n]:" a	
	if [[ -z "$a" ]] || [[ "$a" = "y"  ]] || [[ "$a" = "Y"  ]]
	then
		portlist=$(grep http $file | grep -o " [0-9]\+\/open\/tcp\/\/http[s]\?[?]\?\/" | sort -n | cut -d"/" -f1 | uniq)
	else
		read -p "Do you want to choose the ports? [Y/n]:" b
		if [[ -z "$b" ]] || [[ "$b" = "y"  ]] || [[ "$b" = "Y"  ]]
		then
			read -p "Enter ports (space delimited, e.g. 80 443 8080:" portlist
		else
			echo "OK, exiting"
			exit
		fi
	fi
fi

# Create output directory if it doesn't exist.
if [[ ! -d "$outputdir" ]]
then
	echo ""
	echo "Output directory doesn't exist, creating...."
	echo ""
	mkdir -p "$outputdir"
fi

# Check if portlist contains values, and set defaults if needed.
if [[ -z "$portlist" ]] 
then
	echo "No ports chosen, setting default ports (80/tcp, 443/tcp, 8080/tcp, 8443/tcp)"
	portlist="80 443 8080 8443"
fi

# Define a simple function to catch if a screenshot didn't happen
error_catcher ()
{
if [ "$x" = "" ]; then
     echo "Captured!"
     success=$((success+1)) 
else
     echo "Capture failed. Adding $i:$port to failed-screenshots.txt"
     echo "$i:$port failed" >> failed-screeshots.txt
     failed=$((failed+1))    
fi
}
# change into output directory
cd "$outputdir"

# Actual screenshot stuff
for port in $portlist; do
	#open file, grep for port instances, service type and report how many
	IPlist=$(grep " $port/open" $file | awk '{print $2}')
	count=$(grep " $port/open" $file | awk '{print $2}' | wc -l)
	echo ""
	echo "$count instances of port $port/tcp found"
	echo ""
	#Loop through IPlist and screenshot the ports
	for i in $IPlist; do
		service=$(grep $i $file | grep -o " $port\/open\/tcp\/\/[a-zA-Z0-9?]\+" | cut -d"/" -f5)
		if [[ "$service" = https* || ssl ]]; then
			echo "Taking screenshot of https://$i:$port......."
			x=$((/root/scripts/my-bt-scripts/CutyCapt/CutyCapt --url=https://$i:$port --out=$i-port-$port-01.png --max-wait=20000) 2>&1)
			error_catcher
		elif [[ "$service" = http* ]]; then
			echo "Taking screenshot of http://$i:$port......."
			x=$((/root/scripts/my-bt-scripts/CutyCapt/CutyCapt --url=http://$i:$port --out=$i-port-$port-01.png --max-wait=20000) 2>&1)
			error_catcher
		else
			echo "Nmap hasn't recognised $i:$port as a web service. Adding to failed-screenshots.txt"
			echo "$i:$port identified as $service" >> failed-screeshots.txt
			notwebserv=$((notwebserv+1))
		fi
	done
done
echo "Script complete, $success screenshots taken, $failed failed, $notwebserv not identified as a web service. See failed-screenshots.txt for details"
exit

